#coding:utf-8
from dbutil import MysqldbHelper
from common import exception, utils

db = MysqldbHelper()

class ResponseObject(object):

    def __init__(self, resp_obj):
        """ initialize with a requests.Response object
        @param (requests.Response instance) resp_obj
        """
        self.resp_obj = resp_obj
        self.success = True

    def parsed_body(self):
        try:
            return self.resp_obj.json()
        except ValueError:
            return self.resp_obj.text

    def parsed_dict(self):
        return {
            'status_code': self.resp_obj.status_code,
            'headers': self.resp_obj.headers,
            'body': self.parsed_body()
        }

    def extract_field(self, field, delimiter='.'):
        """ extract field from requests.Response
        @param (str) field of requests.Response object, and may be joined by delimiter
        """
        try:
            field += "."
            top_query, sub_query = field.split(delimiter, 1)

            if top_query in ["body", "content", "text"]:
                json_content = self.parsed_body()
            else:
                json_content = getattr(self.resp_obj, top_query)

            if sub_query:
                return utils.query_json(json_content, sub_query)
            else:
                return json_content

        except AttributeError:
            raise exception.ParamsError("invalid extract_binds!")

    def extract_response(self, extract_binds):
        """ extract content from requests.Response
        @param (list) extract_binds
        @return (list) variable binds list
        """
        extracted_variables_mapping_list = []

        for extract_bind in extract_binds:
            for key, field in extract_bind.items():
                if not isinstance(field, utils.string_type):
                    raise exception.ParamsError("invalid extract_binds!")

                extracted_variables_mapping_list.append(
                    {key: self.extract_field(field)}
                )

        return extracted_variables_mapping_list

    def validate(self, validators, variables_mapping):
        """ Bind named validators to value within the context.
        and get value from sql
        """
        diff_content_list = []

        for validator_dict in validators:

            if "expected" not in validator_dict or "check" not in validator_dict:
                raise exception.ParamsError("expected not specified in validator")

            expect = validator_dict["expected"]
            if type(expect) == str and expect.upper().startswith('SQL'):
                expect = expect.split(':')[1]
                # field = expect.split(" ")[1]
                results = db.select(expect)
                for row in results:
                    validator_dict["expected"] = row[0]

            validator_key = validator_dict["check"]
            try:
                validator_dict["value"] = variables_mapping[validator_key]
            except KeyError:
                validator_dict["value"] = self.extract_field(validator_key)

            match_expected = utils.match_expected(
                validator_dict["value"],
                validator_dict["expected"],
                validator_dict.get("comparator", "eq")
            )

            if not match_expected:
                diff_content_list.append(validator_dict)

        self.success = False if diff_content_list else True
        return diff_content_list